package com.adolph.netty.nio.communicate;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * 〈功能概述〉<br>
 *
 * @author: wangxiangjun
 * @date: 2020-10-02 14:21
 */

public class NIOServer {

    public static void main(String[] args) throws IOException {
        //服务端Channel
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        //选择器
        Selector selector = Selector.open();
        //设置监听
        serverChannel.socket().bind(new InetSocketAddress(8888));
        //设置非阻塞模式
        serverChannel.configureBlocking(false);
        //注册到selector中
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        //循环监听
        while (true){
            if(selector.select(1000) == 0){//等于0没有事件发生，大于0有事件发生
                System.out.println("服务器无连接！");
                continue;
            }
            //获取所有注册的服务端Channel
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            //便利所有的Channel处理对应的事件
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                //对不同事件进行处理
                if(selectionKey.isAcceptable()){
                    System.out.println("建立连接===========");
                    //获取对应客户端的channel
                    SocketChannel clientChannel = serverChannel.accept();
                    if(clientChannel==null){
                        continue;
                    }
                    clientChannel.configureBlocking(false);
                    //注册客户端Channel
                    clientChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                if(selectionKey.isConnectable()){
                    System.out.println("连接成功===========");
                }
                if(selectionKey.isReadable()){
                    System.out.println("读事件===========");
                    //获取到客户端channel
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    //
                    ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment();

                    socketChannel.read(byteBuffer);

                    System.out.println("from 客户端===" + new String(byteBuffer.array()));
                }
                if(selectionKey.isWritable()){
                    System.out.println("写事件===========");
                }

                iterator.remove();

            }
        }

    }
}
